package main

import (
	"fmt"
	"io"
	"os"
	"path"
	"path/filepath"
)

type ChapterFile struct {
}

func main() {
	path1 := "/Users/liuwx/Documents/project/go-demo/chapter-error.go"
	printPathMessage(path1)
	fmt.Println(filepath.Rel("/Users/liuwx/", "/go-demo/chapter-error.go"))
	path2 := "chapter-error.go"
	abs, err := filepath.Abs(path2)
	if err != nil {
		fmt.Println("获取path2 绝度路径时候报错 , ", err.Error())
	}
	fmt.Println("绝对路径:  ", abs)

	// path.join 拼接路径
	fmt.Println(" 当前路径 ", path.Join(path1, "."))
	fmt.Println(" 上一个目录 ", path.Join(path1, ".."))
	fmt.Println("添加前缀目录 ", path.Join("/Users/liuwx/download", path1))
	fmt.Println("添加后缀目录 ", path.Join(path1, "java"))

	chapterFile := ChapterFile{}
	//创建目录
	err, path4, path5 := chapterFile.makeDirInFile(err)

	//创建文件,如果文件存在则被覆盖
	chapterFile.createFile(path5, err)

	//打开文件
	open, err := os.Open(path1)
	if err != nil {
		fmt.Println("打开path1文件时候失败, ", err.Error())
	} else {
		fmt.Println("打开path1文件成功 , ", open)
		if open != nil {
			err := open.Close()
			if err != nil {
				fmt.Printf("关闭 %s 文件错误,错误原因 %s \n", path1, err.Error())
				return

			}
		}
	}

	//以读写方式打开,如果文件不存在的话,就创建
	path7 := "/Users/liuwx/Documents/project/go-demo/test.go"
	file, err := os.OpenFile(path7, os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		fmt.Println("打开path7文件时候失败, ", err.Error())
	} else {
		fmt.Println("打开path7文件成功 , ", file)
		if file != nil {
			err := file.Close()
			if err != nil {
				fmt.Printf("关闭 %s 文件错误,错误原因 %s \n", path7, err.Error())
				return

			}
		}
	}

	//删除文件,注意删除非空目录会失败
	err = os.Remove(path7)
	if err != nil {
		fmt.Println("删除path7文件时候失败, ", err.Error())
	}
	//删除多级目录

	err = os.RemoveAll(path4)
	if err != nil {
		fmt.Printf("删除path4 == %s 目录时候失败,失败原因 %s \n", path4, err.Error())
	}
	//读取文件
	readPath := "/Users/liuwx/Documents/project/go-demo/README.md"
	readFile, err := os.Open(readPath)
	if err != nil {
		fmt.Println("读取 readme文件失败,", err.Error())
	} else {
		bytes := make([]byte, 1024*8, 1024*8)

		for {
			num, err := readFile.Read(bytes)
			if err == nil {
				break
			}
			if num == 0 || err == io.EOF {
				fmt.Println("读取 readme文件失败,", err.Error())
				break
			}
			fmt.Println(string(bytes[:num]))
		}
		err = readFile.Close()
		if err != nil {
			fmt.Println("关闭读取 readme文件失败,", err.Error())
			return
		}
	}
	//写入文件
	testFilePath := "/Users/liuwx/Documents/project/go-demo/abc/efg/test.txt"
	testFile, err := os.OpenFile(testFilePath, os.O_RDWR|os.O_CREATE, os.ModePerm)
	defer func() {
		if testFile != nil {
			err := testFile.Close()
			if err != nil {
				fmt.Println("关闭 testFile 变量 出错 , ", err.Error())
				return
			}
		}
	}()
	if err != nil {
		fmt.Println("打开 testFile 变量 出错 , ", err.Error())
		return
	}
	num, err := testFile.Write([]byte("今天是个好日子"))
	if err != nil {
		fmt.Println("Write 写入 testFile 变量 出错 , ", err.Error())
		return
	}
	fmt.Printf("Write 写入 %d 数据 \n ", num)
	num, err = testFile.WriteString("天天好运来")
	if err != nil {
		fmt.Println("WriteString 写入 testFile 变量 出错 , ", err.Error())
		return
	}

	fmt.Printf("WriteString 写入 %d 数据 \n ", num)
	destFilePath := "/Users/liuwx/Documents/project/go-demo/mkdir/abc/test.txt"
	sourceFile, err := os.Open(testFilePath)
	if err != nil {
		fmt.Printf("打开 testFilePath %s 文件失败 \n ", testFilePath)
		return
	}
	destFile, err := os.OpenFile(destFilePath, os.O_RDWR|os.O_CREATE, os.ModePerm)
	if err != nil {
		fmt.Printf("打开 destFilePath %s 文件失败 \n ", destFilePath)
		return
	}

	defer func(sourceFile *os.File) {
		err := sourceFile.Close()
		if err != nil {
			fmt.Printf("关闭 sourceFile  文件失败,错误原因 %s \n ", err.Error())
		}
	}(sourceFile)

	defer func(destFile *os.File) {
		err := destFile.Close()
		if err != nil {
			fmt.Printf("关闭 destFile  文件失败,错误原因 %s \n ", err.Error())
		}
	}(destFile)
	copyNum, err := io.Copy(destFile, sourceFile)
	if err != nil {
		fmt.Printf("复制文件失败,错误原因 %s \n ", err.Error())
		return
	}
	fmt.Printf("复制文件成功,复制了 %d 内容 \n ", copyNum)

}

func (c *ChapterFile) createFile(path5 string, err error) {
	path6 := path.Join(path5, "test.txt")
	create, err := os.Create(path6)
	if err != nil {
		fmt.Println("创建文件时候失败, ", err.Error())
	} else {
		fmt.Println("创建文件成功 , ", create)
	}
}

func (c *ChapterFile) makeDirInFile(err error) (error, string, string) {
	path3 := "/Users/liuwx/Documents/project/go-demo/mkdir"
	err = os.Mkdir(path3, os.ModePerm)
	if err != nil {
		fmt.Println("创建 mkdir 目录时候失败, ", err.Error())
		return err, "", ""
	}

	//创建多级目录
	path4 := "/Users/liuwx/Documents/project/go-demo/mkdir/abc/efg"
	err = os.MkdirAll(path4, os.ModePerm)
	if err != nil {
		fmt.Println("创建多级 目录时候失败, ", err.Error())
		return err, "", ""
	}

	path5 := "/Users/liuwx/Documents/project/go-demo/abc/efg"
	err = os.MkdirAll(path5, os.ModePerm)
	if err != nil {
		fmt.Println("创建多级 目录时候失败, ", err.Error())
		return err, "", ""
	}
	return nil, path4, path5
}

func printPathMessage(path string) {
	stat, err := os.Stat(path)
	if err != nil {
		fmt.Println("获取文件信息失败,失败原因 ", err.Error())
		return
	}

	fmt.Println("文件名  ", stat.Name())
	fmt.Println("文件权限  ", stat.Mode())
	fmt.Println("文件修改时间  ", stat.ModTime())
	fmt.Println("文件大小  ", stat.Size())
	fmt.Println("文件是否为目录  ", stat.IsDir())

}
